<template>
  <div class="content">
    <!-- 主标题 -->
    <div class="main-title">
      <input
        type="text"
        v-model.trim="main_title"
        :placeholder="default_main_title"
        v-firstSpaceUseless="default_main_title"
      />
    </div>

    <!-- 日期 -->
    <div class="date">
      <input
        type="text"
        v-model.trim="date"
        :placeholder="default_date"
        v-firstSpaceUseless="default_date"
      />
    </div>

    <!-- //? 本周重点工作 -->
    <!-- //* title -->
    <div class="title-item">
      <input
        type="text"
        v-model.trim="title_one"
        :placeholder="titleList[0]"
        v-firstSpaceUseless="titleList[0]"
      />
      <div @click="addTitleItem(CURRENT_WORK)">+</div>
    </div>
    <!-- //todo content -->
    <transition-group name="fadeInUpOutDown" tag="div" class="content-item">
      <ul v-for="item in currentWeekWork" :key="item.id">
        <li>
          <input
            type="text"
            v-model.trim="item.title"
            placeholder="标题 :（ 若为空，默认为“暂无”）"
            v-firstSpaceUseless="'标题 :（ 若为空，默认为“暂无”）'"
            @keydown.enter="addTitleItem(CURRENT_WORK, $event)"
            @keydown.delete="removeTitleItem(CURRENT_WORK, item.id, $event)"
          />
          <div class="add" @click="addContentItem(CURRENT_WORK, item.id)">+</div>
          <div class="remove" @click="removeTitleItem(CURRENT_WORK, item.id)">-</div>
        </li>
        <li v-for="(t, i) in item.contentList" :key="t.id">
          <input
            type="text"
            v-model.trim="item.contentList[i].text"
            placeholder="内容 :"
            v-firstSpaceUseless="'内容 :'"
            @keydown.enter="addContentItem(CURRENT_WORK, item.id, $event)"
            @keydown.delete="removeContentItem(CURRENT_WORK, item.id, t.id, $event)"
          />
          <div class="remove" @click="removeContentItem(CURRENT_WORK, item.id, t.id)">-</div>
        </li>
      </ul>
    </transition-group>

    <!-- //? 下周重点工作 -->
    <!-- //* title -->
    <div class="title-item">
      <input
        type="text"
        v-model.trim="title_two"
        :placeholder="titleList[1]"
        v-firstSpaceUseless="titleList[1]"
      />
      <div @click="addTitleItem(NEXT_WORK)">+</div>
    </div>
    <!-- //todo content -->
    <transition-group name="fadeInUpOutDown" tag="div" class="content-item">
      <ul v-for="item in nextWeekWork" :key="item.id">
        <li>
          <input
            type="text"
            v-model.trim="item.title"
            placeholder="标题 :（ 若为空，默认为“暂无”）"
            v-firstSpaceUseless="'标题 :（ 若为空，默认为“暂无”）'"
            @keydown.enter="addTitleItem(NEXT_WORK, $event)"
            @keydown.delete="removeTitleItem(NEXT_WORK, item.id, $event)"
          />
          <div class="add" @click="addContentItem(NEXT_WORK, item.id)">+</div>
          <div class="remove" @click="removeTitleItem(NEXT_WORK, item.id)">-</div>
        </li>
        <li v-for="(t, i) in item.contentList" :key="t.id">
          <input
            type="text"
            v-model.trim="item.contentList[i].text"
            placeholder="内容 :"
            v-firstSpaceUseless="'内容 :'"
            @keydown.enter="addContentItem(NEXT_WORK, item.id, $event)"
            @keydown.delete="removeContentItem(NEXT_WORK, item.id, t.id, $event)"
          />
          <div class="remove" @click="removeContentItem(NEXT_WORK, item.id, t.id)">-</div>
        </li>
      </ul>
    </transition-group>

    <!-- //? 意见反馈 -->
    <!-- //* title -->
    <div class="title-item">
      <input
        type="text"
        v-model.trim="title_three"
        :placeholder="titleList[2]"
        v-firstSpaceUseless="titleList[2]"
      />
      <div @click="addTitleItem(FEED_BACK)">+</div>
    </div>
    <!-- //todo content -->
    <transition-group name="fadeInUpOutDown" tag="div" class="content-item">
      <ul v-for="item in feedback" :key="item.id">
        <li>
          <input
            type="text"
            v-model.trim="item.title"
            placeholder="标题 :（ 若为空，默认为“暂无”）"
            v-firstSpaceUseless="'标题 :（ 若为空，默认为“暂无”）'"
            @keydown.enter="addTitleItem(FEED_BACK, $event)"
            @keydown.delete="removeTitleItem(FEED_BACK, item.id, $event)"
          />
          <div class="add" @click="addContentItem(FEED_BACK, item.id)">+</div>
          <div class="remove" @click="removeTitleItem(FEED_BACK, item.id)">-</div>
        </li>
        <li v-for="(t, i) in item.contentList" :key="t.id">
          <input
            type="text"
            v-model.trim="item.contentList[i].text"
            placeholder="内容 :"
            v-firstSpaceUseless="'内容 :'"
            @keydown.enter="addContentItem(FEED_BACK, item.id, $event)"
            @keydown.delete="removeContentItem(FEED_BACK, item.id, t.id, $event)"
          />
          <div class="remove" @click="removeContentItem(FEED_BACK, item.id, t.id)">-</div>
        </li>
      </ul>
    </transition-group>

    <!-- //? 培训需求 -->
    <!-- //* title -->
    <div class="title-item">
      <input
        type="text"
        v-model.trim="title_four"
        :placeholder="titleList[3]"
        v-firstSpaceUseless="titleList[3]"
      />
      <div @click="addTitleItem(TRAIN_DEMAND)">+</div>
    </div>
    <!-- //todo content -->
    <transition-group name="fadeInUpOutDown" tag="div" class="content-item">
      <ul v-for="item in trainDemand" :key="item.id">
        <li>
          <input
            type="text"
            v-model.trim="item.title"
            placeholder="标题 :（ 若为空，默认为“暂无”）"
            v-firstSpaceUseless="'标题 :（ 若为空，默认为“暂无”）'"
            @keydown.enter="addTitleItem(TRAIN_DEMAND, $event)"
            @keydown.delete="removeTitleItem(TRAIN_DEMAND, item.id, $event)"
          />
          <div class="add" @click="addContentItem(TRAIN_DEMAND, item.id)">+</div>
          <div class="remove" @click="removeTitleItem(TRAIN_DEMAND, item.id)">-</div>
        </li>
        <li v-for="(t, i) in item.contentList" :key="t.id">
          <input
            type="text"
            v-model.trim="item.contentList[i].text"
            placeholder="内容 :"
            v-firstSpaceUseless="'内容 :'"
            @keydown.enter="addContentItem(TRAIN_DEMAND, item.id, $event)"
            @keydown.delete="removeContentItem(TRAIN_DEMAND, item.id, t.id, $event)"
          />
          <div class="remove" @click="removeContentItem(TRAIN_DEMAND, item.id, t.id)">-</div>
        </li>
      </ul>
    </transition-group>

    <!-- 待解决问题 -->
    <div class="title-item">
      <input
        type="text"
        v-model.trim="title_five"
        :placeholder="titleList[4]"
        v-firstSpaceUseless="titleList[4]"
      />
      <div @click="addTitleItem(PROBLEM_TODO)">+</div>
    </div>
    <!-- //todo content -->
    <transition-group name="fadeInUpOutDown" tag="div" class="content-item">
      <ul v-for="item in problemTodo" :key="item.id">
        <li>
          <input
            type="text"
            v-model.trim="item.title"
            placeholder="标题 :（ 若为空，默认为“暂无”）"
            v-firstSpaceUseless="'标题 :（ 若为空，默认为“暂无”）'"
            @keydown.enter="addTitleItem(PROBLEM_TODO, $event)"
            @keydown.delete="removeTitleItem(PROBLEM_TODO, item.id, $event)"
          />
          <div class="add" @click="addContentItem(PROBLEM_TODO, item.id)">+</div>
          <div class="remove" @click="removeTitleItem(PROBLEM_TODO, item.id)">-</div>
        </li>
        <li v-for="(t, i) in item.contentList" :key="t.id">
          <input
            type="text"
            v-model.trim="item.contentList[i].text"
            placeholder="内容 :"
            v-firstSpaceUseless="'内容 :'"
            @keydown.enter="addContentItem(PROBLEM_TODO, item.id, $event)"
            @keydown.delete="removeContentItem(PROBLEM_TODO, item.id, t.id, $event)"
          />
          <div class="remove" @click="removeContentItem(PROBLEM_TODO, item.id, t.id)">-</div>
        </li>
      </ul>
    </transition-group>

    <mail-info :showPanel="panel" @update:showPanel="val => (panel = val)"></mail-info>
    <div class="btn-ops">
      <button @click="recoverFromDraft" v-if="isExistDraft">从草稿中恢复</button>
      <button @click="saveDraft">保存草稿{{ draftMessage }}</button>
      <button @click="exportWord">我要导出Word</button>
      <button @click="sendMail">我要发邮件</button>
    </div>
  </div>
</template>

<script>
import { nanoid } from "nanoid"
import { mapMutations } from "vuex"
import { createWordBuffer } from "../utils/word_template"
import mailInfo from "./mail-info"
import getFingerprint from "../utils/Fingerprint"
export default {
  components: {
    mailInfo,
  },
  directives: {
    firstSpaceUseless: {
      bind(el, binding, vnode) {
        el.InputHandle = function(event) {
          let value = event.target.value.trim()
          if (!value) {
            event.target.value = ""
            event.target.placeholder = binding.value
          }
        }
        el.BlurHandle = function() {
          vnode.context.saveDraft()
        }

        el.addEventListener("input", el.InputHandle)
        el.addEventListener("blur", el.BlurHandle)
      },
      unbind(el, binding, vnode) {
        el.removeEventListener("input", el.InputHandle)
        el.removeEventListener("blur", el.BlurHandle)
      },
    },
  },
  data: function() {
    return {
      panel: false,
      main_title: "",
      default_main_title: "郑州开发中心",
      date: "",
      title_one: "",
      title_two: "",
      title_three: "",
      title_four: "",
      title_five: "",
      titleList: [
        "一、本周完成重点工作",
        "二、下周重点工作",
        "三、意见反馈",
        "四、培训需求",
        "五、待解决问题",
      ],
      currentWeekWork: [
        {
          id: nanoid(),
          title: "",
          contentList: [],
        },
      ],
      nextWeekWork: [
        {
          id: nanoid(),
          title: "",
          contentList: [],
        },
      ],
      feedback: [
        {
          id: nanoid(),
          title: "",
          contentList: [],
        },
      ],
      trainDemand: [
        {
          id: nanoid(),
          title: "",
          contentList: [],
        },
      ],
      problemTodo: [
        {
          id: nanoid(),
          title: "",
          contentList: [],
        },
      ],
      CURRENT_WORK: 1,
      NEXT_WORK: 2,
      FEED_BACK: 3,
      TRAIN_DEMAND: 4,
      PROBLEM_TODO: 5,
      prevExportTime: 0,
      draftMessage: "",
      isExistDraft: false,
    }
  },
  watch: {
    all_data: {
      handler(val) {
        this.updateWord(val)
      },
      immediate: true,
      deep: true,
    },
  },
  computed: {
    default_date: function() {
      let date = new Date()
      let year = date.getFullYear()
      let month = (date.getMonth() + 1).toString().padStart(2, "0")
      let day = date
        .getDate()
        .toString()
        .padStart(2, "0")
      return `（${year}年${month}月${day}日）`
    },

    all_data: {
      get() {
        // 过滤无效数据
        let list = Object.values(this.options())
        let content = []
        list.forEach(listName => {
          let data = []
          this[listName].forEach(item => {
            if (item.title) {
              let list_ = item.contentList.filter(val => val.text)
              data.push({ title: item.title, list: list_ })
            }
          })
          if (!data.length) {
            data.push({ title: "暂无", list: [] })
          }
          content.push(data)
        })

        let title = this.main_title ? this.main_title : this.default_main_title
        let date = this.date ? this.date : this.default_date
        let titleList = ["title_one", "title_two", "title_three", "title_four", "title_five"]
        let sectionTitle = titleList.map((item, i) => {
          return this[item] ? this[item] : this.titleList[i]
        })
        return {
          title,
          date,
          sectionTitle,
          content,
        }
      },

      set(val) {
        const { content, date, sectionTitle, title } = val
        const list = Object.values(this.options())
        list.forEach((listName, i) => {
          this[listName] = content[i].map(v => ({
            id: nanoid(),
            title: v.title,
            contentList: v.list,
          }))
        })
        this.main_title = title
        this.date = date
        this.titleList = sectionTitle
      },
    },
  },
  methods: {
    ...mapMutations(["updateWord"]),

    allData() {
      return [
        "main_title",
        "date",
        "title_one",
        "title_two",
        "title_three",
        "title_four",
        "title_five",
        "currentWeekWork",
        "nextWeekWork",
        "feedback",
        "trainDemand",
        "problemTodo",
      ]
    },

    options() {
      return {
        [this.CURRENT_WORK]: "currentWeekWork",
        [this.NEXT_WORK]: "nextWeekWork",
        [this.FEED_BACK]: "feedback",
        [this.TRAIN_DEMAND]: "trainDemand",
        [this.PROBLEM_TODO]: "problemTodo",
      }
    },

    addTitleItem(type, event) {
      let option = this.options()
      this[option[type]].push({
        id: nanoid(),
        title: "",
        contentList: [],
      })
      /* 通过回车触发，添加一个兄弟输入框，并触发focus事件 */
      if (event && event.key === "Enter") {
        this.$nextTick(() => {
          this.focusTextBox(event.target, 1)
        })
      }
    },

    removeTitleItem(type, id, event) {
      let option = this.options()
      let delIndex = this[option[type]].findIndex(item => item.id === id)
      // 保留最后一个标题，清空文本框和子文本
      if ((!event || (event && event.key === "Delete")) && this[option[type]].length === 1) {
        this[option[type]][0].title = ""
        this[option[type]][0].contentList = []
        return
      }
      if (event && event.key === "Delete") {
        this[option[type]].splice(delIndex, 1)
        /* 通过delete键触发，自动聚焦上一个文本框 */
        this.focusTextBox(event.target, -1)
      } else if (!event) {
        this[option[type]].splice(delIndex, 1)
      }
    },

    addContentItem(type, id, event) {
      let option = this.options()
      let contentList = this[option[type]].find(item => item.id === id).contentList
      contentList.push({ id: nanoid(), text: "" })
      if (event && event.key === "Enter") {
        this.$nextTick(() => {
          this.focusTextBox(event.target, 1)
        })
      }
    },

    removeContentItem(type, id, tid, event) {
      let option = this.options()
      let contentList = this[option[type]].find(item => item.id === id).contentList
      let delIndex = contentList.findIndex(item => item.id === tid)
      if (event && event.key === "Delete") {
        contentList.splice(delIndex, 1)
        this.focusTextBox(event.target, -1)
      } else if (!event) {
        contentList.splice(delIndex, 1)
      }
    },

    /* 自动聚焦上/下一个文本框 */
    focusTextBox(target, type) {
      let inputList = document.getElementsByTagName("input")
      for (let i = 0; i < inputList.length; i++) {
        if (inputList[i] === target) {
          inputList[i + type].focus()
        }
      }
    },

    /* 保存草稿 */
    saveDraft() {
      if (localStorage && window.localStorage) {
        const key = `WEEK_REPORT_${process.env.NODE_ENV.toUpperCase()}_DRAFT_DATA`
        localStorage.setItem(key, JSON.stringify(this.all_data))
      }
      this.draftMessage = "成功"
      setTimeout(() => {
        this.draftMessage = ""
      }, 500)
    },

    async exportWord() {
      /* 设置节流：每三秒只能触发一次导出 */
      if (Date.now() - this.prevExportTime < 3000) return
      this.prevExportTime = Date.now()
      this.$axios
        .post("/recordExportWord", {
          data: {
            userName: this.all_data.title,
            fingerprint: await getFingerprint(),
          },
        })
        .then(res => {
          if (res.data.message) {
            createWordBuffer(this.all_data).then(buffer => {
              let url = window.URL.createObjectURL(new Blob([buffer]))
              let a = document.createElement("a")
              a.download = `${this.all_data.title}.docx`
              a.href = url
              a.click()
            })
          }
        })
        .catch(err => {
          console.log(err)
        })
    },

    sendMail() {
      this.panel = true
    },

    /* 校验服务器是否开启 */
    checkServerIsOnline() {
      this.$axios.get("/").then(res => {
        if (res.status === 200) {
          console.log("%cserver is online", "color: #56d85c")
        }
      })
    },

    /* 获取当前周的周一到周五的日期范围 */
    getWeekRangeDate() {
      let currentTime = new Date()
      let year = currentTime.getFullYear()
      let month = currentTime.getMonth()
      let date = currentTime.getDate()
      let day = currentTime.getDay() || 7
      let currentMonthDayNums = new Date(year, month + 1, 0).getDate()
      let monday = new Date(year, month + 1, date - day + 1 - currentMonthDayNums)
      let friday = new Date(year, month + 1, date - day + 5 - currentMonthDayNums)
      return `（${this.formatDate(monday)} - ${this.formatDate(friday)}）`
    },

    /* 将localstorage转为年月日格式 */
    formatDate(date) {
      return `${date.getFullYear()}年${(date.getMonth() + 1).toString().padStart(2, "0")}月${date
        .getDate()
        .toString()
        .padStart(2, "0")}日`
    },

    /* 设置标题和日期默认值 */
    init() {
      /* 从缓存中获取标题 */
      if (window.localStorage && window.localStorage.info) {
        this.main_title = JSON.parse(window.localStorage.info).title
      }

      /* 检验草稿是否存在 */
      const key = `WEEK_REPORT_${process.env.NODE_ENV.toUpperCase()}_DRAFT_DATA`
      this.isExistDraft = window.localStorage && window.localStorage[key]

      /* 设置日期范围 */
      this.date = this.getWeekRangeDate()
    },

    /* 从草稿中恢复 */
    recoverFromDraft() {
      const key = `WEEK_REPORT_${process.env.NODE_ENV.toUpperCase()}_DRAFT_DATA`
      this.all_data = JSON.parse(window.localStorage[key])
    },
  },
  mounted() {
    this.checkServerIsOnline()
    this.init()
  },
}
</script>

<style lang="scss" scoped>
/* .fadeInUpOutDown-enter-active {
  opacity: 0;
  transform: translateY(20px);
  transition: 1s;
}
.fadeInUpOutDown-enter-to {
  opacity: 1;
  transform: translateY(0px);
}
.fadeInUpOutDown-leave-active {
  position: absolute;
  width: 100%;
  opacity: 0.5;
  transform: translateY(-1px);
}
.fadeInUpOutDown-leave-to {
  opacity: 0;
  transform: translateY(10px);
}
.fadeInUpOutDown-move {
  transition: all 1s;
} */

.content {
  position: relative;
  padding: 50pt 72pt;

  input {
    border: none;
    outline: none;
    font-family: "微软雅黑";

    &:focus {
      outline: 1px solid #666;
    }
  }
}

.main-title {
  display: flex;
  justify-content: center;
  height: 50px;
  border-radius: 3px;

  input {
    flex: 1;
    text-align: center;
    font-size: 29px;
    font-weight: bold;
    border-radius: inherit;
  }
}

.date {
  display: flex;
  justify-content: center;
  margin-top: 5px;
  height: 35px;
  border-radius: 3px;

  input {
    flex: 1;
    text-align: center;
    font-size: 16px;
    border-radius: inherit;
  }
}

.title-item {
  display: flex;
  position: relative;
  margin-top: 5px;
  height: 40px;
  line-height: 50px;
  border-radius: 3px;
  transition: 0.5s;

  input {
    width: 100%;
    padding-left: 6px;
    font-size: 21px;
    font-weight: bold;
    border-radius: inherit;
  }

  div {
    position: absolute;
    top: 4px;
    right: 10px;
    width: 30px;
    height: 30px;
    text-align: center;
    line-height: 30px;
    font-weight: bold;
    border-radius: 5px;
    // box-shadow: 0px 0px 3px #ccc;
    transition: 0.5s;
    opacity: 1;
    cursor: pointer;
    user-select: none;
    border: 1px solid #ccc;

    &:active {
      transform: scale(0.95);
    }
  }
}

.content-item {
  font-size: 14px;
  position: relative;

  margin-top: 5px;
  margin-bottom: 7px;

  ul {
    list-style: none;
    margin-bottom: 5px;

    &:last-child {
      margin-bottom: 0;
    }

    li {
      position: relative;
      margin-bottom: 5px;
      line-height: 30px;
      height: 30px;
      border-radius: 3px;
      transition: 0.5s;
      background: #fff;

      &:last-child {
        margin-bottom: 0;
      }

      input {
        width: calc(100% - 8px);
        height: 100%;
        padding-left: 6px;
        border-radius: inherit;
      }

      div {
        position: absolute;
        top: 4px;
        width: 20px;
        height: 20px;
        text-align: center;
        line-height: 20px;
        border-radius: 3px;
        cursor: pointer;
        opacity: 1;
        transition: 0.5s;
        user-select: none;
        border: 1px solid #ccc;
        // box-shadow: 0px 0px 2px #ccc;

        &.add {
          right: 40px;
        }

        &.remove {
          right: 10px;
          font-size: 18px;
        }
      }
    }

    li:not(:first-child) {
      margin-left: 5px;
    }
  }
}

.export-word {
  position: absolute;
  left: 10px;
  top: 40%;
}

.btn-ops {
  display: flex;
  gap: 10px;
}
</style>
